import express, { Request, Response, Router } from 'express';
import { PrismaClient } from '@prisma/client';
import { adminAuthMiddleware } from '../../middleware/adminAuth';
import { ApiResponse } from '../../utils/response';
import { priceService } from '../../services/priceService';

const router: Router = express.Router();
const prisma = new PrismaClient();

// 获取提现申请列表
router.get('/list', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const {
      status,
      page = 1,
      limit = 20,
      startDate,
      endDate,
      userId,
      minAmount,
      maxAmount,
      exportAll = 'false' // 新增：导出全部数据参数
    } = req.query;

    // 获取当前登录用户信息
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminRole = (req as any).adminRole;
    const adminId = (req as any).adminId;

    // 构建查询条件
    const where: any = {};

    // 权限过滤：USER角色（推荐人）只能查看自己邀请的用户的提现记录
    if (userType === 'USER' && currentUserId) {
      // 查询该用户邀请的所有用户ID
      const referredUsers = await prisma.user.findMany({
        where: { referredBy: currentUserId },
        select: { id: true }
      });

      const referredUserIds = referredUsers.map(u => u.id);

      // 如果没有邀请任何用户，返回空列表
      if (referredUserIds.length === 0) {
        res.json(ApiResponse.success({
          records: [],
          summary: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total: 0,
            totalPages: 0
          }
        }));
        return;
      }

      // 限制只能查看邀请用户的提现记录
      where.userId = { in: referredUserIds };
    }

    // 权限过滤：PARTNER角色（合作伙伴）只能查看自己邀请码注册的用户的提现记录
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && adminId) {
      // 查询该合作伙伴邀请的所有用户ID
      const partnerUsers = await prisma.user.findMany({
        where: { partnerAdminId: adminId },
        select: { id: true }
      });

      const partnerUserIds = partnerUsers.map(u => u.id);

      // 如果没有关联任何用户，返回空列表
      if (partnerUserIds.length === 0) {
        res.json(ApiResponse.success({
          records: [],
          summary: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pagination: {
            page: Number(page),
            limit: Number(limit),
            total: 0,
            totalPages: 0
          }
        }));
        return;
      }

      // 限制只能查看关联用户的提现记录
      where.userId = { in: partnerUserIds };
    }

    if (status && status !== 'all') {
      where.status = status as string;
    }

    if (userId) {
      where.userId = parseInt(userId as string);
    }

    if (minAmount || maxAmount) {
      where.amount = {};
      if (minAmount) where.amount.gte = parseFloat(minAmount as string);
      if (maxAmount) where.amount.lte = parseFloat(maxAmount as string);
    }

    if (startDate || endDate) {
      where.createdAt = {};
      if (startDate) where.createdAt.gte = new Date(startDate as string);
      if (endDate) {
        const endDateTime = new Date(endDate as string);
        endDateTime.setHours(23, 59, 59, 999);
        where.createdAt.lte = endDateTime;
      }
    }

    // 判断是否导出全部
    const isExportAll = exportAll === 'true';

    // 获取提现记录
    const withdrawsRaw = await prisma.withdrawRecord.findMany({
      where,
      include: {
        user: {
          select: {
            id: true,
            name: true,
            idNumber: true,
            mobileNumber: true,
            mobileCarrier: true
          }
        }
      },
      orderBy: { createdAt: 'desc' },
      ...(isExportAll ? {} : {
        skip: (Number(page) - 1) * Number(limit),
        take: Number(limit)
      })
    });

    // 格式化数据，将Decimal转换为number
    const withdraws = withdrawsRaw.map(w => ({
      ...w,
      amount: Number(w.amount),
      withdrawType: w.withdrawType || 'BALANCE' // 添加提现类型
    }));

    // 获取总记录数
    const total = await prisma.withdrawRecord.count({ where });

    // 统计信息
    const summary = await prisma.withdrawRecord.groupBy({
      by: ['status'],
      where: status && status !== 'all' ? {} : where,
      _count: {
        status: true
      },
      _sum: {
        amount: true
      }
    });

    const statusSummary = {
      pending: { count: 0, amount: 0 },
      confirmed: { count: 0, amount: 0 },
      failed: { count: 0, amount: 0 },
      cancelled: { count: 0, amount: 0 }
    };

    summary.forEach(s => {
      const status = s.status.toLowerCase() as keyof typeof statusSummary;
      if (statusSummary[status]) {
        statusSummary[status].count = Number(s._count.status);
        statusSummary[status].amount = Number(s._sum.amount) || 0;
      }
    });

    res.json(ApiResponse.success({
      records: withdraws,
      summary: statusSummary,
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total: Number(total),
        totalPages: Math.ceil(Number(total) / Number(limit))
      }
    }));
  } catch (error) {
    console.error('출금 목록 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 목록 조회에 실패했습니다.'));
  }
});

// 获取提现申请详情
router.get('/:id', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminRole = (req as any).adminRole;
    const adminId = (req as any).adminId;

    const withdraw = await prisma.withdrawRecord.findUnique({
      where: { id: parseInt(id) },
      include: {
        user: {
          select: {
            id: true,
            name: true,
            idNumber: true,
            mobileNumber: true,
            mobileCarrier: true,
            createdAt: true,
            referredBy: true,
            partnerAdminId: true
          }
        }
      }
    });

    if (!withdraw) {
      res.status(404).json(ApiResponse.error('출금 기록이 존재하지 않습니다.'));
      return;
    }

    // 权限检查：USER角色（推荐人）只能查看自己邀请用户的提现记录
    if (userType === 'USER' && currentUserId) {
      if (withdraw.user.referredBy !== currentUserId) {
        res.status(403).json(ApiResponse.error('이 출금 기록에 접근할 권한이 없습니다.'));
        return;
      }
    }

    // 权限检查：PARTNER角色（合作伙伴）只能查看自己邀请码注册用户的提现记录
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && adminId) {
      if (withdraw.user.partnerAdminId !== adminId) {
        res.status(403).json(ApiResponse.error('이 출금 기록에 접근할 권한이 없습니다.'));
        return;
      }
    }

    // 获取用户余额信息
    const userBalance = await prisma.userBalance.findUnique({
      where: { userId: withdraw.userId }
    });

    // 获取用户最近的提现历史
    const recentWithdraws = await prisma.withdrawRecord.findMany({
      where: {
        userId: withdraw.userId,
        id: { not: withdraw.id }
      },
      select: {
        id: true,
        amount: true,
        status: true,
        createdAt: true,
        processedAt: true
      },
      orderBy: { createdAt: 'desc' },
      take: 5
    });

    // 获取用户今日提现统计
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const tomorrow = new Date(today);
    tomorrow.setDate(tomorrow.getDate() + 1);

    const todayWithdraws = await prisma.withdrawRecord.aggregate({
      where: {
        userId: withdraw.userId,
        status: { in: ['PENDING', 'CONFIRMED'] },
        createdAt: {
          gte: today,
          lt: tomorrow
        }
      },
      _sum: {
        amount: true
      },
      _count: {
        id: true
      }
    });

    res.json(ApiResponse.success({
      withdraw,
      userBalance,
      recentWithdraws,
      todayStats: {
        totalAmount: Number(todayWithdraws._sum.amount) || 0,
        count: todayWithdraws._count.id
      }
    }));
  } catch (error) {
    console.error('출금 상세 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 상세 조회에 실패했습니다.'));
  }
});

// 处理提现申请（승인/거부）
router.post('/:id/process', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { action, note } = req.body; // action: 'confirm' | 'reject'
    const adminId = (req as any).adminId;
    const adminName = (req as any).adminName;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminRole = (req as any).adminRole;

    if (!['confirm', 'reject'].includes(action)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 작업입니다. confirm 또는 reject만 가능합니다.'));
      return;
    }

    // 获取提现记录
    const withdraw = await prisma.withdrawRecord.findUnique({
      where: { id: parseInt(id) },
      include: {
        user: {
          select: {
            name: true,
            idNumber: true,
            referredBy: true,
            partnerAdminId: true
          }
        }
      }
    });

    if (!withdraw) {
      res.status(404).json(ApiResponse.error('출금 기록이 존재하지 않습니다.'));
      return;
    }

    // 权限检查：USER角色（推荐人）只能处理自己邀请用户的提现申请
    if (userType === 'USER' && currentUserId) {
      if (withdraw.user.referredBy !== currentUserId) {
        res.status(403).json(ApiResponse.error('이 출금 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    // 权限检查：PARTNER角色（合作伙伴）只能处理自己邀请码注册用户的提现申请
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && adminId) {
      if (withdraw.user.partnerAdminId !== adminId) {
        res.status(403).json(ApiResponse.error('이 출금 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    if (withdraw.status !== 'PENDING') {
      res.status(400).json(ApiResponse.error('해당 출금 신청은 이미 처리되어 다시 처리할 수 없습니다.'));
      return;
    }

    if (action === 'confirm') {
      // 승인提现：解冻资金并标记为已处理
      const result = await prisma.$transaction(async (tx) => {
        // 更新提现记录상태
        const updatedWithdraw = await tx.withdrawRecord.update({
          where: { id: parseInt(id) },
          data: {
            status: 'CONFIRMED',
            adminNote: note || `관리자 ${adminName}가 출금을 승인했고 자금이 송금되었습니다.`,
            processedBy: adminId,
            processedAt: new Date()
          }
        });

        // 所有提现都会冻结KRW余额，这里统一扣减冻结金额并更新总资产
        await tx.userBalance.update({
          where: { userId: withdraw.userId },
          data: {
            frozen: { decrement: withdraw.amount },
            total: { decrement: withdraw.amount }
          }
        });

        return updatedWithdraw;
      });

      res.json(ApiResponse.success(result, `출금 신청이 승인되었습니다: 사용자 ${withdraw.user.name}의 ${Number(withdraw.amount).toLocaleString('ko-KR')}원이 ${withdraw.bankName} ${withdraw.bankAccount}로 송금되었습니다.`));
    } else {
      // 거부提现：解冻资金并恢复到可用余额
      const result = await prisma.$transaction(async (tx) => {
        // 更新提现记录상태
        const updatedWithdraw = await tx.withdrawRecord.update({
          where: { id: parseInt(id) },
          data: {
            status: 'FAILED',
            adminNote: note || `관리자 ${adminName}가 출금을 거부했습니다.`,
            processedBy: adminId,
            processedAt: new Date()
          }
        });

        // 统一恢复冻结金额到可用余额
        await tx.userBalance.update({
          where: { userId: withdraw.userId },
          data: {
            balance: { increment: withdraw.amount },
            frozen: { decrement: withdraw.amount }
          }
        });

        // 如果本次提现使用了质押收益，返还对应的NEAR可提余额
        if (Number(withdraw.rewardNearAmount) > 0) {
          const rewardAmount = Number(withdraw.rewardNearAmount);
          const stakingRecord = await tx.userStaking.findFirst({
            where: { userId: withdraw.userId }
          });

          if (stakingRecord) {
            await tx.userStaking.update({
              where: { userId: withdraw.userId },
              data: {
                availableRewards: {
                  increment: rewardAmount
                }
              }
            });
          }
        }

        return updatedWithdraw;
      });

      res.json(ApiResponse.success(result, `출금 신청이 거부되었습니다. 사용자 ${withdraw.user.name}의 금액이 복원되었습니다: ${note || '거절 사유가 제공되지 않았습니다.'}`));
    }
  } catch (error) {
    console.error('출금 신청 처리 오류:', error);
    res.status(500).json(ApiResponse.error('출금 신청 처리에 실패했습니다.'));
  }
});

// 批量处理提现申请
router.post('/batch-process', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { withdrawIds, action, note } = req.body;
    const adminId = (req as any).adminId;
    const adminName = (req as any).adminName;
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminRole = (req as any).adminRole;

    if (!Array.isArray(withdrawIds) || withdrawIds.length === 0) {
      res.status(400).json(ApiResponse.error('처리할 출금 신청을 선택해 주세요.'));
      return;
    }

    if (!['confirm', 'reject'].includes(action)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 작업입니다.'));
      return;
    }

    // 获取所有待处理的提现记录
    const withdraws = await prisma.withdrawRecord.findMany({
      where: {
        id: { in: withdrawIds.map(id => parseInt(id)) },
        status: 'PENDING'
      },
      include: {
        user: {
          select: {
            name: true,
            referredBy: true,
            partnerAdminId: true
          }
        }
      }
    });

    if (withdraws.length === 0) {
      res.status(400).json(ApiResponse.error('처리할 수 있는 출금 신청이 없습니다.'));
      return;
    }

    // 权限检查：USER角色（推荐人）只能批量处理自己邀请用户的提现申请
    if (userType === 'USER' && currentUserId) {
      const unauthorizedWithdraws = withdraws.filter(w => w.user.referredBy !== currentUserId);
      if (unauthorizedWithdraws.length > 0) {
        res.status(403).json(ApiResponse.error('일부 출금 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    // 权限检查：PARTNER角色（合作伙伴）只能批量处理自己邀请码注册用户的提现申请
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && adminId) {
      const unauthorizedWithdraws = withdraws.filter(w => w.user.partnerAdminId !== adminId);
      if (unauthorizedWithdraws.length > 0) {
        res.status(403).json(ApiResponse.error('일부 출금 기록을 처리할 권한이 없습니다.'));
        return;
      }
    }

    let successCount = 0;
    let totalAmount = 0;

    for (const withdraw of withdraws) {
      try {
        await prisma.$transaction(async (tx) => {
          if (action === 'confirm') {
            // 출금을 일괄 승인
            await tx.withdrawRecord.update({
              where: { id: withdraw.id },
              data: {
                status: 'CONFIRMED',
                adminNote: note || `관리자 ${adminName}가 출금을 일괄 승인했습니다.`,
                processedBy: adminId,
                processedAt: new Date()
              }
            });

            // 统一扣减冻结金额和总资产
            await tx.userBalance.update({
              where: { userId: withdraw.userId },
              data: {
                frozen: { decrement: withdraw.amount },
                total: { decrement: withdraw.amount }
              }
            });
          } else {
            // 출금을 일괄 거부
            await tx.withdrawRecord.update({
              where: { id: withdraw.id },
              data: {
                status: 'FAILED',
                adminNote: note || `관리자 ${adminName}가 출금을 일괄 거부했습니다.`,
                processedBy: adminId,
                processedAt: new Date()
              }
            });

            // 解冻金额并恢复到可用余额
            await tx.userBalance.update({
              where: { userId: withdraw.userId },
              data: {
                balance: { increment: withdraw.amount },
                frozen: { decrement: withdraw.amount }
              }
            });

            // 返还被扣减的可提收益
            if (Number(withdraw.rewardNearAmount) > 0) {
              const rewardAmount = Number(withdraw.rewardNearAmount);
              const stakingRecord = await tx.userStaking.findFirst({
                where: { userId: withdraw.userId }
              });

              if (stakingRecord) {
                await tx.userStaking.update({
                  where: { userId: withdraw.userId },
                  data: {
                    availableRewards: {
                      increment: rewardAmount
                    }
                  }
                });
              }
            }
          }
        });

        successCount++;
        totalAmount += Number(withdraw.amount);
      } catch (error) {
            console.error(`출금 ${withdraw.id} 처리에 실패했습니다:`, error);
      }
    }

    const actionText = action === 'confirm' ? '승인' : '거부';
    res.json(ApiResponse.success({
      successCount,
      totalCount: withdraws.length,
      totalAmount
    }, `일괄 ${actionText} 완료: 처리 ${successCount}건, 총액 ${totalAmount.toLocaleString('ko-KR')}원`));
  } catch (error) {
    console.error('출금 신청 일괄 처리 오류:', error);
    res.status(500).json(ApiResponse.error('출금 신청 일괄 처리에 실패했습니다.'));
  }
});

// 获取提现统计数据
router.get('/stats/overview', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { period = 'today' } = req.query; // today, week, month, year

    // 获取当前登录用户信息
    const userType = (req as any).userType;
    const currentUserId = (req as any).userId;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    let startDate: Date;
    const endDate = new Date();

    switch (period) {
      case 'week':
        startDate = new Date();
        startDate.setDate(startDate.getDate() - 7);
        break;
      case 'month':
        startDate = new Date();
        startDate.setMonth(startDate.getMonth() - 1);
        break;
      case 'year':
        startDate = new Date();
        startDate.setFullYear(startDate.getFullYear() - 1);
        break;
      default: // today
        startDate = new Date();
        startDate.setHours(0, 0, 0, 0);
        break;
    }

    // 构建查询条件
    const whereCondition: any = {
      createdAt: {
        gte: startDate,
        lte: endDate
      }
    };

    // 权限过滤：USER角色和PARTNER角色只能查看自己邀请用户的提现统计
    if (userType === 'USER' && currentUserId) {
      const referredUsers = await prisma.user.findMany({
        where: { referredBy: currentUserId },
        select: { id: true }
      });
      if (referredUsers.length === 0) {
        // 如果没有邀请任何用户，返回空统计
        res.json(ApiResponse.success({
          stats: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pendingCount: 0,
          pendingAmount: 0,
          hourlyTrend: [],
          period
        }));
        return;
      }
      whereCondition.userId = { in: referredUsers.map(u => u.id) };
    } else if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      const partnerUsers = await prisma.user.findMany({
        where: { partnerAdminId: adminId },
        select: { id: true }
      });
      if (partnerUsers.length === 0) {
        // 如果没有用户，返回空统计
        res.json(ApiResponse.success({
          stats: {
            pending: { count: 0, amount: 0 },
            confirmed: { count: 0, amount: 0 },
            failed: { count: 0, amount: 0 },
            cancelled: { count: 0, amount: 0 }
          },
          pendingCount: 0,
          pendingAmount: 0,
          hourlyTrend: [],
          period
        }));
        return;
      }
      whereCondition.userId = { in: partnerUsers.map(u => u.id) };
    }

    // 获取统计数据
    const stats = await prisma.withdrawRecord.groupBy({
      by: ['status'],
      where: whereCondition,
      _count: {
        status: true
      },
      _sum: {
        amount: true
      }
    });

    // 获取待处理的提现申请数量
    const pendingWhere: any = { status: 'PENDING' };
    if (whereCondition.userId) {
      pendingWhere.userId = whereCondition.userId;
    }
    const pendingCount = await prisma.withdrawRecord.count({
      where: pendingWhere
    });

    // 获取待处理的출금 금额
    const pendingAmount = await prisma.withdrawRecord.aggregate({
      where: pendingWhere,
      _sum: {
        amount: true
      }
    });

    // 获取今日提现趋势（按小时）
    const hourlyStats = await prisma.$queryRaw`
      SELECT 
        HOUR(created_at) as hour,
        COUNT(*) as count,
        SUM(amount) as amount
      FROM withdraw_records 
      WHERE DATE(created_at) = CURDATE()
        AND status = 'CONFIRMED'
      GROUP BY HOUR(created_at)
      ORDER BY hour
    ` as Array<{ hour: number; count: bigint; amount: string }>;

    const formattedStats = {
      pending: { count: 0, amount: 0 },
      confirmed: { count: 0, amount: 0 },
      failed: { count: 0, amount: 0 },
      cancelled: { count: 0, amount: 0 }
    };

    stats.forEach(s => {
      const status = s.status.toLowerCase() as keyof typeof formattedStats;
      if (formattedStats[status]) {
        formattedStats[status].count = s._count.status;
        formattedStats[status].amount = Number(s._sum.amount) || 0;
      }
    });

    res.json(ApiResponse.success({
      stats: formattedStats,
      pendingCount: Number(pendingCount),
      pendingAmount: Number(pendingAmount._sum.amount) || 0,
      hourlyTrend: hourlyStats.map(h => ({
        hour: h.hour,
        count: Number(h.count),
        amount: parseFloat(h.amount) || 0
      })),
      period
    }));
  } catch (error) {
    console.error('출금 통계 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 통계 조회에 실패했습니다.'));
  }
});

// 导出提现记录（Excel格式数据）
router.get('/export/records', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { 
      status, 
      startDate, 
      endDate, 
      limit = 1000 
    } = req.query;

    // 构建查询条件
    const where: any = {};
    
    if (status && status !== 'all') {
      where.status = status as string;
    }
    
    if (startDate || endDate) {
      where.createdAt = {};
      if (startDate) where.createdAt.gte = new Date(startDate as string);
      if (endDate) {
        const endDateTime = new Date(endDate as string);
        endDateTime.setHours(23, 59, 59, 999);
        where.createdAt.lte = endDateTime;
      }
    }

    // 获取提现记录
    const withdraws = await prisma.withdrawRecord.findMany({
      where,
      include: {
        user: {
          select: {
            name: true,
            idNumber: true,
            mobileNumber: true
          }
        }
      },
      orderBy: { createdAt: 'desc' },
      take: Number(limit)
    });

    // 格式化数据为Excel友好格式
    const exportData = withdraws.map(w => ({
      '출금 ID': w.id,
      '사용자 이름': w.user.name,
      '주민등록번호': w.user.idNumber,
      '휴대폰 번호': w.user.mobileNumber,
      '출금 금액': Number(w.amount),
      '은행명': w.bankName,
      '은행 계좌': w.bankAccount,
      '계좌 명의자': w.accountHolder,
      '상태': w.status,
      '신청 시간': w.createdAt.toLocaleString('ko-KR'),
      '처리 시간': w.processedAt ? w.processedAt.toLocaleString('ko-KR') : '',
      '관리자 비고': w.adminNote || ''
    }));

    res.json(ApiResponse.success({
      data: exportData,
      totalRecords: exportData.length,
      exportTime: new Date().toISOString()
    }, '출금 기록 내보내기가 완료되었습니다.'));
  } catch (error) {
    console.error('출금 기록 내보내기 오류:', error);
    res.status(500).json(ApiResponse.error('출금 기록 내보내기에 실패했습니다.'));
  }
});

export default router;
